package com.biboheart.adapter.core.impl;

import com.biboheart.adapter.core.Collector;
import com.biboheart.adapter.support.utils.ObjectTypeUtils;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class NormalCollector implements Collector {
    private final Map<String, Object> dataHash = new HashMap<>();

    public NormalCollector(Object input) {
        this.pushHash("root", input);
    }

    @Override
    public Object getObject(String path) {
        if (null == path) {
            return dataHash;
        }
        return dataHash.get(path);
    }

    @SuppressWarnings("unchecked")
    private void pushHash(String path, Object input) {
        if (null == input) return;
        boolean isList = (input instanceof List);
        List<Object> list = !isList ? null : ObjectTypeUtils.convertType(input, List.class);
        if (!isList) {
            dataHash.put(path, input);
            Map<String, Object> nextObjectMap = nextLevelObject(input);
            if (null != nextObjectMap && !nextObjectMap.isEmpty()) {
                for (Map.Entry<String, Object> entry : nextObjectMap.entrySet()) {
                    pushHash(path + "." + entry.getKey(), entry.getValue());
                }
            }
        } else {
            dataHash.put(path, input);
            for (int i = 0; i < list.size(); i++) {
                String key = path + "[" + i + "]";
                Object obj = list.get(i);
                dataHash.put(key, obj);
                Map<String, Object> nextObjectMap = nextLevelObject(obj);
                if (null != nextObjectMap && !nextObjectMap.isEmpty()) {
                    for (Map.Entry<String, Object> entry : nextObjectMap.entrySet()) {
                        pushHash(key + "." + entry.getKey(), entry.getValue());
                    }
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    private Map<String, Object> nextLevelObject(Object input) {
        if (ObjectTypeUtils.isPrimitive(input)) return null;
        Map<String, Object> objectsMap = new HashMap<>();
        if (input instanceof Map) {
            Map<String, Object> map = ObjectTypeUtils.convertType(input, Map.class);
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                Object obj = entry.getValue();
                if (ObjectTypeUtils.isPrimitive(obj)) continue;
                objectsMap.put(key, obj);
            }
        } else {
            Class<?> clazz = input.getClass();
            Field[] fields = clazz.getDeclaredFields();//获得属性
            for (Field field : fields) {
                try {
                    /*PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                    Method getMethod = pd.getReadMethod();//获得get方法
                    Object obj = getMethod.invoke(input);//此处为执行该Object对象的get方法*/
                    field.setAccessible(true);
                    Object obj =  field.get(input);
                    if (ObjectTypeUtils.isPrimitive(obj)) continue;
                    objectsMap.put(field.getName(), obj);
                } catch (IllegalAccessException ignored) {
                }
            }
        }
        return objectsMap;
    }
}
